#include "snake.h"

struct  Snake{
	uint8	Direction,
   //目标点xy
			Snake_XPos
			Snake_YPos,
			Count_Node;//蛇的节数
}Snake;

struct Food{
    //x.y坐标 
	uint8	Food_X,
			Food_Y;
}Food;

//在 24*16的范围内任意点画点(每点4*4大小) 
//画一个小方块
//x y坐标为方块左下角的那一点
void Big_Pix(uint8 x,uint8 y,uint8 val)
{
    uint8 t1,t2;
	Write_cmd(0x36);//扩充指令 绘图显示开
    for(t1=0;t1<4;t1++)
    for(t2=0;t2<4;t2++)
		LCD_Point(4*x+t1,4*y+t2,val);
	Write_cmd(0x36);//扩充指令 绘图显示开 
}
//读取某一点的值
//x=0~127 y=0~63
uint8 lcd_readPoint(x,y)
{
	uint8 X_Pos,Y_Pos,date1,date2;
	Y_Pos=y/16;
	X_Pos=x/16;
	switch (Y_Pos)
	{
		case 0:Y_Pos=0x90+15-y%16;X_Pos=0x88+x/16;
			break;
		case 1:Y_Pos=0x80+15-y%16;X_Pos=0x88+x/16;
			break;
		case 2:Y_Pos=0x90+15-y%16;X_Pos=0x80+x/16;
			break;
		case 3:Y_Pos=0x80+15-y%16;X_Pos=0x80+x/16;
		default:
			break;
	}

	//Write_cmd(0x34);//扩充指令 绘图显示开
	Write_cmd(Y_Pos);//扩充指令 绘图显示开
	Write_cmd(X_Pos);//扩充指令 绘图显示开
	Read_Date();//假读取数据一次
	date1=Read_Date();//高		   0x0f,0xf0
	date2=Read_Date();//低

	if(x%16<8)
	{
		if(date1&(0x01 << (7 - x%16)))
			return 1; 
			//Write_date(date1 | (0x01 << (7 - x%16)) );
	}
	else
	{
		if(date2&(0x01 << (15 - x%16)))
			return 1;
			//Write_date(date2|(0x01 << (15 - x%16)));
	}
	return 0;		
}

//读取指定位置的一点 
//x:0~23;y:0~15
//此点为空时返回0，否则返回1
uint8 ReadPix(uint8 x,uint8 y)
{  
    uint8 lcdram=0; 
    x=x*4;y=y*4;//得到每个方块左下角的坐标 24*4=96 16*4=64 
    lcdram=lcd_readPoint(x,y);//读出点位置
    if(lcdram&0x01)return 1;
    else return 0; 
}
void Snake_Init(uint8 x, uint8 y,uint8 length)
{
	uint8 i ;
	uint8 Position;
	GAME_OVER = 0;//清结束标志
	Snake.Direction = GO_RIGHT;//尝试能否使用rand函数
	Snake.Count_Node = length;//蛇身长度,但是length从哪来
	LCD_ClearGDRAM();//清屏 lcdsram            
	//觉得这种方法不好
	for(i=0;i<length;i++)	
		Big_Pix(x+i,y,1);//填充length
	while(1)
	{
		//利用定时器随机得到种子
		srand(timer0_count);
		position = rand()>>4;//产生随机数 32768/16=2048
		if(Hit_Self(position%24,position/128))continue;//如果落在有点处则重新产生   x=0~23  y=0~15    
		Big_Pix(position%24,position/128,1);//填充
		Snake.XPos = position%24;//设置目标点
		Snake.YPos = position/128;
		break;
	}
}

//判断蛇是否碰到自己身体
uint8 Hit_Self(uint8 x,uint8 y)//x=0-23,y=0->15 24*4=96,16*4=64
{
	return ReadPix(x,y);//读取指定位置的一点
}


void Snake_Gui(void)
{
	uint8 i = 0;
	Write_cmd(0x36);//扩充指令,绘图显示开
	//画线
	LCD_DrawLine(96,0,96,63);//画游戏界面和分数界面的分界线
	Write_cmd(0x30);//扩充指令 绘图显示开
	LCD_Pos(1,6);//设置坐标
	LCD_String("LEV");//发送字符串 等级
	LCD_Pos(2,7);//设置坐标
	LCD_String("级");//发送字符串 等级
	LCD_Pos(3,6);//设置坐标
	if(PAUSE)
	{
		LCD_String("PAU";//发送字符串暂停
	}	
	else
	{
		LCD_String("SCO")//发送字符串 分数
	}
}

void Game_Over_Show(void)
{
	//清屏
	LCD_ClearGDRAM();//清空 LCDSRAM
	LCD_ClearDDRAM();//清空ddram
	Write_cmd(0x30);//扩充指令 绘图显示开
	///显示分数//最高分
	LCD_Pos(1,0);//设置坐标
	LCD_String("Max Score:")//显示最高分数
    if(GAME_TYPE==0)//snake game
    {    
        if(MAXSCORE_Snake<score)MAXSCORE_Snake=score;//修改最高分值
		LCD_Pos(1,6);//设置坐标
		LCD_Shownum(MAXSCORE_Snake,4);
        if(score==MAXSCORE_Snake)
		{
			LCD_Pos(2,0);//设置坐标     
			LCD_String("Well Done!");//玩家创造了最高分	
		}
	    else
		{
			LCD_Pos(2,0);//设置坐标     
			LCD_String("Game Over!");//游戏结束			
		}
	}
//	else //russia game
//    {    
//        if(MAXSCORE_Russia<score)MAXSCORE_Russia=score;
//        Show_num2(0,84,MAXSCORE_Russia/100);//russia game max score
//        Show_num2(0,96,MAXSCORE_Russia%100);  
//        if(score==MAXSCORE_Russia)LCD_write_cstr(1,36,"Well Done!");//玩家创造了最高分 
//	    else LCD_write_cstr(1,36,"Game Over!");  //游戏结束
//	}          
	Delay_1000ms(2000);
	LCD_Pos(3,0);//设置坐标     
	LCD_String("Your Score:");//显示玩者分数
	LCD_Pos(3,6);//设置坐标
	LCD_Shownum(score,4);
	Delay_1000ms(2000);	
	GAME_PLAY=0;//关闭游戏模式
	Timer0_70msInit();//开启定时器0 70ms模式
}

//显示游戏时的分数和等级信息 
void Snake_Msg(void)
{
	Write_cmd(0x30);//扩充指令 绘图显示开
	LCD_Pos(2,6);//设置坐标
	LCD_Shownum(LEVEL,2);
	LCD_Pos(4,6);//设置坐标
	LCD_Shownum(score,4);                 
}
//产生新的种子,即下一个点
//同时对蛇身的身体长度加一
uint8 SeedGet(void)
{    
    unsigned int position,i; 
    Snake_Data.Dot_Cnt+=1;//点加1 
    score+=10;//分数加10 
    if(Snake_Data.Dot_Cnt>MAX_LENTH)//如果长度达到最大值，则进行下一关
    {
        if(LEVEL<MAX_LEVEL_Snake)//如果关数没有到达最大关数，则进行下一关，否则就是通关
        {
            LEVEL++;//级别增加
        }
        else PASS=1; //过通关  
        Snake_Msg();    
        Snake_Ini(0,0,2);
		PAUS=1;//关闭暂停
		for(i=0;i<30;i++)
		{
			snake_body[i]=0;
		}
		Snake_GUI(); 
        Delay_1000ms(2000);  
        //key=255;
        return 0;
    }
    Snake_Msg();   
    while(1)//重新计算新目标点
    {
		srand(timer0_count);//得到种子
        position = rand()>>4;
		if(Hit_Self(position%24,position/128))
		{
			Delay_1000ms(10);
			continue;//直到得合适的坐标 24*16以内			
		}
		Big_Pix(position%24,position/128,1);
		Snake_Data.Next_X = position%24;
		Snake_Data.Next_Y = position/128;
		break;
    }    
    //Big_Pix(Snake_Data.Next_X,Snake_Data.Next_Y,1);//显示新的食物 
    Delay_1000ms(500);//延时,避免死  
    return 1;
}
void Snake_Run(void)
{
	//取得蛇头xy坐标
	 = Snake_Body_X[0];
	 = Snake_Body_Y[0];

	switch(Snake.Direction)
	{
		case:GO_UP
		
		case:GO_DOWN
		
		case:GO_LEFT

		case:GO_RIGHT
	}
	if(!GAME_OVER)
	{
		//得到食物的判断
		//蛇头和食物无重叠表示没有得到食物
		//保留蛇尾
			
	}	
	else//得到食物处理
	{
		
	}
}
//进行游戏,主循环.
void Play_Snake(void)
{       
    unsigned int lev;
	Timer0_1msInit();
    if(LEVELEPM_Snake>MAX_LEVEL_Snake)LEVELEPM_Snake=18;//初始化等级 
    else LEVEL=LEVELEPM_Snake;
    if(MAXSCORE_Snake>9999)MAXSCORE_Snake=0;//初始化分数   
    
    Snake_GUI(); 
    score=0;  //分数清空
    PAUS=1;//关闭暂停 
    GAME_PLAY=1;//游戏模式
    PASS=0;//通关标志清空
    Snake_Msg();//显示游戏时的分数和等级信息 
	while(!GAME_OVER)
	{
		//GAME_key=JOYPAD_NUM();
		if(GAME_key!=255)
		{
			//SendDate(GAME_key);//测试用的语句，测试是否收到了游戏手柄的信息
			switch(GAME_key)//根据按键方向确定移动方向 不可向相反方向移动
			{
				case TO_RIGHT :if(Snake_Data.Direction!=TO_LEFT)Snake_Data.Direction = TO_RIGHT;break;
				case TO_LEFT  :if(Snake_Data.Direction!=TO_RIGHT)Snake_Data.Direction = TO_LEFT;break;
				case TO_UP    :if(Snake_Data.Direction!=TO_DOWN)Snake_Data.Direction = TO_UP;break;
				case TO_DOWN  :if(Snake_Data.Direction!=TO_UP)Snake_Data.Direction = TO_DOWN;break;
				case PAUSE://暂停
				{
				    PAUS=!PAUS;  
				    Snake_GUI();//改变gui
				    break;
				}
				case GAME_KEY_D://水平增加
				{
					if(PAUS)
					{
						if(LEVEL<MAX_LEVEL_Snake-1)LEVEL++;
					    else LEVEL=0;
					    Snake_Msg();//更新显示 	
					}
					break;
				}
				case GAME_KEY_E://水平增加
				{
					if(PAUS)
					{
					    if(LEVEL>0)LEVEL--;
					    else LEVEL=MAX_LEVEL_Snake-1;
					    Snake_Msg();//更新显示
					} 
				    break;
				}
//				/*case LEVAND://水平减少
//				{
//				    if(LEVEL<MAX_LEVEL_Snake)LEVEL++;
//				    else LEVEL=MAX_LEVEL_Snake; 
//				    Snake_Msg();//更新显示
//				    break;
//				}  
//				case SAVELEV://保存LEVEL信息
//				{               
//				    Cleardisplay(4);//清屏
//				    LEVELEPM_Snake=LEVEL;//保存等级信息
//				    save_show();//显示保存时的界面
//				    Snake_GUI();   
//				    Snake_Msg(); //恢复显示
//				    lcd_refresh();//刷新 
//				    READY=0;//清除按键标志 
//				    break; 
//				}	*/
				case GAME_KEY_B://无条件退出
				{
					GAME_PLAY=0;//return ;
					GAME_OVER=1;
					break;
				}
				default:
					break;
			}
			key_flag=1;
			GAME_key=255;		
		}
 
		if(PASS)//过通关了!!!
		{
			LCD_ClearGDRAM();//清屏 lcdsram
			LCD_ClearDDRAM();//清空DDRAM  
            
			LCD_Pos(2,0);//设置坐标     
			LCD_String("Well Done! Dude.");//显示最高分
		    Delay_1000ms(2000);

			LCD_ClearDDRAM();//清空DDRAM
			LCD_Pos(2,0);//设置坐标     
			LCD_String("Congratulations!");//显示最高分
		    Delay_1000ms(2000);

			GAME_OVER=1;//游戏结束
		}
		if(!PAUS)	Snake_Run();//如果撞倒四周和自己就gameover了
		else Snake_GUI();//更新信息 
		lev=LEVEL;
		lev=(MAX_LEVEL_Snake-lev)*20+40;
		Delay_1000ms(lev);//级别延时控制 
	}
	Game_Over_Show(0);//snake game  
} 
